#include "ScheduleTableModel.h"

/*
ScheduleTableModel::ScheduleTableModel(void)
{

}
*/


ScheduleTableModel::ScheduleTableModel(korlapAdmin_model* model, QLocale* locale)
{
	lastHovered.first = -1;
	lastHovered.second = -1;
	cellToHover.first = -1;
	cellToHover.second = -1;
	this->hoveredRow = -1;
	this->editing = false;
	initializeFreeHourBrush();
	initializeReservedHourBrush();
	initializeCurrentHourBrush();
	initializeHoveredFreeBrush();
	this->extendList = new QList<QPair<QPair<int,int>,int>>();
	this->model = model;
	this->locale = locale;
	this->siesta = false;
	this->night = false;
	this->nextWeek = NULL;
	this->prevWeek = NULL;
	this->weekRange = model->calculateDaysOfThisWeek();

	if(QTime::currentTime() < this->beginningOfMorningShift)
	{
		this->currentShift = MORNING;
	}
	else if(QTime::currentTime() < this->endOfMorningShift)
	{
		this->currentShift = MORNING;
	}else if(QTime::currentTime() < this->beginningOfNightShift)
	{
		this->currentShift = SIESTA;
	}else if(QTime::currentTime() < this->endOfNightShift)
	{
		this->currentShift = AFTERNOON;
	}else if(QTime::currentTime() >= this->endOfMorningShift)
	{
		this->currentShift = NIGHT;
	}

	try{
		model->getScheduleMapForThisWeek();
	}catch(Exception e)
	{
		throw e;
		//messageBox->setText("Fatal error: could not retrieve data for the scheduler. " + e.getMessage());
		//messageBox->exec();
	}
	}

void ScheduleTableModel::initializeHoveredFreeBrush()
{
	QColor color(255,255,130,100);
	QColor colorEnd(255,255,50,150);
	QLinearGradient gradient(0,0,300,10);
	gradient.setColorAt(0,color);
	gradient.setColorAt(1,colorEnd);
	this->hoveredFreeBrush = new QBrush(gradient);
}
ScheduleTableModel::~ScheduleTableModel(void)
{
}



QList<QPair<QPair<int,int>,int>> *ScheduleTableModel::getRowsToSpan()
{
	QMap<QDateTime*,Schedule*>* map;
	
	try
	{
		map =model->getScheduleMapForThisWeek();
			
		QMap<QDateTime*,Schedule*>::iterator it = map->begin();;
		for(;it != map->end();it++)
		{
			Schedule * s = (*it);
			QTime startTime = s->getStartDate()->time();
			QTime endTime = s->getEndDate()->time();
			if(startTime != endTime)
			{
				// the minimual resolution is fifteen minutes so we're working with quarters
				int quarterDif = (startTime.hour() - this->beginningOfMorningShift.hour())*4;
				int startRow = quarterDif + (startTime.minute() / 15);
				int difRows = startTime.secsTo(endTime)/900;
				int column = (s->getStartDate()->date().dayOfWeek() + 2) % 7 - 1;
				extendList->append(QPair<QPair<int,int>,int>(QPair<int,int>(startRow,column), difRows));
			}
			
		}

	}catch(Exception e)
	{
		throw e;
	}
	return extendList;
}

int ScheduleTableModel::rowCount(const QModelIndex&) const
{
	/*
	if(!siesta && ! night)
		return (this->endOfMorningShift.hour() - this->beginningOfMorningShift.hour())*4 + (this->endOfNightShift.hour()-this->beginningOfMorningShift.hour())*4;
	else if(siesta && night)
		return 48;
	else if(siesta && ! night)
		return (this->endOfNightShift.hour()- this->beginningOfMorningShift.hour())*4;
	else if(!siesta && night)
		return (this->endOfMorningShift.hour()-this->beginningOfMorningShift.hour())*4 + (this->endOfNightShift.hour() - this->beginningOfNightShift.hour())*4 + 16;
*/
		return 64;
}

void ScheduleTableModel::initializeFreeHourBrush()
{
	QColor color(0,255,0,60);
	QColor colorEnd(0,200,0,150);

	QLinearGradient gradient(0,0,130,10);
	gradient.setColorAt(0,color);
	gradient.setColorAt(1,colorEnd);
	this->freeHourBrush = new QBrush(gradient);
}

void ScheduleTableModel::initializeReservedHourBrush()
{
	QColor color2(255,0,0,100);
	QColor color2End(150,0,0);
	QLinearGradient gradientReserved(0,0,300,10);
	gradientReserved.setColorAt(0,color2);
	gradientReserved.setColorAt(1,color2End);
	this->reservedHourBrush = new QBrush(gradientReserved);
}
void ScheduleTableModel::initializeCurrentHourBrush()
{
	QColor color(0,200,150,100);
	QColor colorEnd(0,255,255,255);
	QLinearGradient gradient(0,0,300,10);
	gradient.setColorAt(0,color);
	//gradient.setColorAt(1,colorEnd);
	this->currentHourFreeBrush = new QBrush(gradient);
}

int ScheduleTableModel::columnCount(const QModelIndex&) const
{
	return 6;
}

void ScheduleTableModel::refreshTable()
{
	emit this->dataChanged(index(0,0), index(this->rowCount(),this->columnCount()));
}

void ScheduleTableModel::hoverCell(const QModelIndex& index)
{
	this->hoveredRow = index.row();
	emit this->dataChanged(this->index(index.row(),0),this->index(index.row(),this->columnCount()-1));
}

void ScheduleTableModel::unHoverCell()
{
	int i = 0;
}
QVariant ScheduleTableModel::data(const QModelIndex &index, int role) const
{
	Schedule* s = NULL;
	int row = index.row();
	int column = index.column();
	try{
		QDateTime* time = model->getCurrentTimeTable()[row][column];
		s = model->getSchedule(time);
	}catch(Exception e)
	{
		QString str = e.getMessage();
		return QVariant();
	}	
	switch(role)
	{
	case Qt::DisplayRole:

			/*
			unsigned int p_id = s->getVisit()->getPatientId();
				QString name = model->getPatientManager()->findPatientByFileNumber(p_id)->getName();
			QString note = s->getNote();
			QString Stime = s->getStartDate()->time().toString("hh:mm");
			QString Etime = s->getEndDate()->time().toString("hh:mm");
			return Stime + " - " + Etime + "\n" + name + " [" + note + "]";
			*/
		break;
	case Qt::TextAlignmentRole:
		return Qt::AlignCenter;
		break;
	case Qt::FontRole:
		break;
	case Qt::BackgroundRole:
		if(cellToHover.first == index.row() && cellToHover.second == index.column())
		{
			return brushHovered(s);
		}
		break;
	}
	return QVariant();
}


Qt::ItemFlags ScheduleTableModel::flags ( const QModelIndex & index ) const
{
	return 35;
}

QBrush ScheduleTableModel::brushHovered(Schedule* s)const
{
	if(!s)
	{
		return *this->hoveredFreeBrush;
	}
	else
	{
		return QBrush();
	}
}

QBrush ScheduleTableModel::brushItem(Schedule* s)const
{
	if(!s)
	{
		return *freeHourBrush;
	}
	else if(currentSelectedPatient == model->getPatientManager()->findPatientByFileNumber(s->getVisit()->getPatientId()))
	{
		return *this->hoveredFreeBrush;
	}
	else
	{
		return *reservedHourBrush;
	}
}

QBrush ScheduleTableModel::brushYellow()const
{
	QColor color(255,255,130,100);
	QColor colorEnd(255,255,50,150);
	QLinearGradient gradient(0,0,300,10);
	gradient.setColorAt(0,color);
	gradient.setColorAt(1,colorEnd);
	QBrush brush(gradient);
	return brush;	
}

const Patient* ScheduleTableModel::getPatient()const
{
	return this->currentSelectedPatient;
}

void ScheduleTableModel::setPatient(const Patient* p)
{
	this->currentSelectedPatient = p;
}
QBrush ScheduleTableModel::brushGreen()const
{
	QColor color(0,255,0,60);
	QColor colorEnd(0,200,0,150);

	QLinearGradient gradient(0,0,130,10);
	gradient.setColorAt(0,color);
	gradient.setColorAt(1,colorEnd);
	QBrush brush(gradient);
	return brush;
}

QBrush ScheduleTableModel::brushRed()const
{
	QColor color2(255,0,0,100);
	QColor color2End(150,0,0);
	QLinearGradient gradientReserved(0,0,300,10);
	gradientReserved.setColorAt(0,color2);
	gradientReserved.setColorAt(1,color2End);
	QBrush redBrush(gradientReserved);
	return redBrush;
}
void ScheduleTableModel::setModel(korlapAdmin_model* model)
{
	this->model = model;
}

QPair<QDateTime*,QDateTime*>* ScheduleTableModel::getWeekRange()
{
	return this->weekRange;
}



QVariant ScheduleTableModel::headerData ( int section, Qt::Orientation orientation, int role ) const
{
	if (role != Qt::DisplayRole)
         return QVariant();

	if(orientation == Qt::Horizontal)
	{
		int day = (section+5)%7;
		return locale->dayName(day+1) + " (" + weekRange->first->date().addDays(section).toString("dd. MMM") + ")";
	}
	else if(orientation == Qt::Vertical)
		return this->beginningOfMorningShift.addSecs(900*section).toString("hh:mm ");
	return QVariant();
		
}

void ScheduleTableModel::setMorningStart(const QTime& time)
{
	this->beginningOfMorningShift = time;
}

void ScheduleTableModel::setMorningEnd(const QTime &time)
{
	this->endOfMorningShift = time;
}

void ScheduleTableModel::setNightStart(const QTime &time)
{
	this->beginningOfNightShift = time;
}

void ScheduleTableModel::setNightEnd(const QTime &time)
{
	this->endOfNightShift = time;
}

QTime ScheduleTableModel::getMorningEnd()
{
	return this->endOfMorningShift;
}

QTime ScheduleTableModel::getMorningStart()
{
	return this->beginningOfMorningShift;
}

QTime ScheduleTableModel::getNightStart()
{
	return this->beginningOfNightShift;
}

QTime ScheduleTableModel::getNightEnd()
{
	return this->endOfNightShift;
}

void ScheduleTableModel::setHoveredRow(int row)
{
	this->hoveredRow = row;
}

void ScheduleTableModel::setEditing(bool e)
{
	this->editing = e;
}

void ScheduleTableModel::addSchedule(const QString& note)
{
	int firstRow = getSelectedCells().first.row();
	int firstCol = getSelectedCells().first.column();
	int lastRow = getSelectedCells().second.row();
	int lastCol = getSelectedCells().second.column();
	QDateTime*** timeTable = this->model->getCurrentTimeTable();
	QDateTime* t1 = timeTable[firstRow][firstCol];
	QDateTime* t2 = timeTable[lastRow+1][lastCol];
	if(getPatient())
	{
		try{
			model->addSchedule(this->getPatient()->getFilenr(),t1,t2,note);
		}
		catch(Exception e)
		{
			throw e;
		}
	}
	else
	{
		
	}
}

void ScheduleTableModel::setSelectedCells(const QPair<QPersistentModelIndex,QPersistentModelIndex>& lst)
{
	this->selectedCells = lst;
}
int ScheduleTableModel::getHoveredRow() const
{
	return this->hoveredRow;
}
